<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>文档</title>
  <link href="./css/semantic/semantic.min.css" rel="stylesheet">
  <link href="./css/oscTree.css" rel="stylesheet">
  <link href="./css/markdown.css" rel="stylesheet">
  <link href="./css/index.css" rel="stylesheet">
</head>
<body>
  <div class="ui container">
    <div id="project-title">
      <div class="title-wrap">
        <div class="left">
          <i class="icon eye"></i>
          文档预览:
          <span id="preview-title"></span>
        </div>
        <div class="right">
          Export by Gitee
        </div>
      </div>
    </div>

    <div class="ui container" id="wiki-preview-container">
      <div id="wiki-preview">
        <div class="ui segment">
          <div class="ui grid page">
            <div class="three wide column doc-list">
              <div class="title">
                <a id="ex-all">
                  收缩全部章节
                </a>
              </div>
              <div class="ztree" id="tree"></div>
            </div>
            <div class="thirteen wide column doc-content">
              <div id="page-detail">
                <div class="title">
                </div>
                <div class="content markdown-body">
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      </div>
  </div>
</body>
</html>
<script src="./js/jquery.min.js"></script>
<script src="./js/ztree.all.js"></script>
<script src="./js/jquery.ztree.exhide.min.js"></script>
<script>
  var zTreeObj;var expandStatus=true;$(document).ready(function(){var setting={view:{showLine:true,showIcon:true},callback:{onClick:function(e,treeId,treeNode){if(treeNode!==null&&!treeNode.isParent&&typeof(treeNode.children)==="undefined"){var sort_id=treeNode.sort_id;var content=json_data.content;for(var c in content){if(c==sort_id){$("#page-detail .title").html(treeNode.name);$("#page-detail .content").html(content[c]);return false}}}else{zTreeObj.expandNode(treeNode)}}},data:{simpleData:{enable:true}}};zTreeObj=$.fn.zTree.init($("#tree"),setting,json_data.title);var first_content=json_data.title[0];$("#page-detail .title").html(first_content.name);$("#page-detail .content").html(json_data.content[first_content.sort_id]);$("#preview-title").html(json_data.preview_title);$("#ex-all").on("click",function(e){zTreeObj.expandAll(!expandStatus);expandStatus=!expandStatus;if(expandStatus){$(this).text("收缩全部章节")}else{$(this).text("展开全部章节")}})});
</script><script>var json_data = {"preview_title":"javascript函数式编程库","title":[{"id":"000000000000介绍","pId":0,"name":"介绍","parent":null,"order":0,"sort_id":2161093,"extname":".md","isParent":false,"isHidden":false,"content":"\u003Ch1\u003E\n\u003Ca id=\"javascript-函数式编程的接口库\" class=\"anchor\" href=\"#javascript-%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%BA%93\"\u003E\u003C/a\u003Ejavascript 函数式编程的接口库\u003C/h1\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E模仿\u003Ca href=\"http://www.underscore-js.com/sourceread/index.html\"\u003Eunderscore.js\u003C/a\u003E实现自己的函数库，增加额外自己常用的函数，用于学习函数式编程\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Cul\u003E\n\u003Cli\u003E使用es6实现部分\u003Ca href=\"http://www.underscore-js.com/\"\u003Eunderscore.js\u003C/a\u003E的函数，增加自己常用的\u003C/li\u003E\n\u003Cli\u003E增加自己常用到的函数，如\u003Ccode\u003EonceDelay\u003C/code\u003E(运行一次后在指定时间后才能再次运行)\u003C/li\u003E\n\u003Cli\u003E错误处理：\n\u003Cul\u003E\n\u003Cli\u003E指定参数类型才能运行函数\u003C/li\u003E\n\u003Cli\u003E检测运行时函数是否为必须，必须时没传函数控制台输出提示信息\u003C/li\u003E\n\u003C/ul\u003E\n\u003C/li\u003E\n\u003Cli\u003E单元测试\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch2\u003E\n\u003Ca id=\"目录结构\" class=\"anchor\" href=\"#%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84\"\u003E\u003C/a\u003E目录结构\u003C/h2\u003E\n\u003Cpre\u003E\u003Ccode\u003E+ browserTest // 浏览器单元测试环境  \n  |-- index.html\n+ lib  \n  |-- functional.js // 函数库  \n+ mochawesome-report  \n  |-- mochawesome.html // 单元测试报告\n+ doc 文档  \n  |-- index_with_tree\n+ test 单元测试  \n  |-- functional.test.js // 测试用例代码  \n  |-- spec.html // 测试用例规格  \n\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2\u003E\n\u003Ca id=\"运行单元测试\" class=\"anchor\" href=\"#%E8%BF%90%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95\"\u003E\u003C/a\u003E运行单元测试\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003Enode\u003C/strong\u003E\u003C/p\u003E\n\u003Cpre\u003E\u003Ccode\u003Enpm install -g mocha mochawesome\nnpm install\nnpm run test\n\n// 生成测试报告\nnpm run report\n// 生成测试用例规格\nnpm run spec\n\u003C/code\u003E\u003C/pre\u003E\n\u003Cp\u003E\u003Cstrong\u003E浏览器\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E直接打开\u003Ccode\u003EbrowserTest/index.html\u003C/code\u003E\u003C/p\u003E"},{"id":"000000000000使用","pId":0,"name":"使用","parent":null,"order":1,"sort_id":2161094,"extname":".md","isParent":false,"isHidden":false,"content":"\u003Cp\u003E\u003Cstrong\u003E安装\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E浏览器： 通过\u003Ccode\u003E\u0026lt;script\u0026gt;\u003C/code\u003E引入，默认绑定全局变量 _\u003C/li\u003E\n\u003Cli\u003Enode: \u003Ccode\u003Erequire\u003C/code\u003E 引入\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E统一\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E传入 \u003Cstrong\u003E[context]\u003C/strong\u003E，在function中的this会指向[context]\u003C/li\u003E\n\u003Cli\u003E当传入不合符函数的参数类型时，会返回自身（有想过返回undefined），不会去运行函数\u003C/li\u003E\n\u003Cli\u003E当函数参数中 \u003Cstrong\u003Efunction\u003C/strong\u003E 为必传时，没传控制台会输出提示信息\u003C/li\u003E\n\u003Cli\u003E参数带 [ ] 为选填，如[context]\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E9%9B%86%E5%90%88\"\u003E集合(数组或对象)\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#each\"\u003Eeach\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#map\"\u003Emap\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#reduce\"\u003Ereduce\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#find\"\u003Efind\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#filter\"\u003Efilter\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#every\"\u003Eevery\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#some\"\u003Esome\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#max\"\u003Emax\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#min\"\u003Emin\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#contains\"\u003Econtains\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#size\"\u003Esize\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isEmpty\"\u003EisEmpty\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E6%95%B0%E7%BB%84\"\u003E数组\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#last\"\u003Elast\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#unique\"\u003Eunique\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#range\"\u003Erange\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E5%87%BD%E6%95%B0\"\u003E函数\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#partial\"\u003Epartial\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#memoize\"\u003Ememoize\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#curry\"\u003Ecurry\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#delay\"\u003Edelay\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#curry\"\u003Ethrottle\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#debounce\"\u003Edebounce\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#once\"\u003Eonce\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#pipe\"\u003Epipe\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E5%AF%B9%E8%B1%A1\"\u003E对象\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#hasKey\"\u003EhasKey\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isEqual\"\u003EisEqual\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#inMatch\"\u003EinMatch\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isObject\"\u003EisObject\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isArray\"\u003EisArray\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isFunction\"\u003EisFunction\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isPromise\"\u003EisPromise\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isDate\"\u003EisDate\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isRegExp\"\u003EisRegExp\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isMap\"\u003EisMap\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isSet\"\u003EisSet\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isString\"\u003EisString\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isNumber\"\u003EisNumber\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isNull\"\u003EisNull\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isNaN\"\u003EisNaN\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isUndefined\"\u003EisUndefined\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isSymbol\"\u003EisSymbol\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E5%AE%9E%E7%94%A8%E5%8A%9F%E8%83%BD\"\u003E实用功能\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#random\"\u003Erandom\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#formatDate\"\u003EformatDate\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#noConflict\"\u003EnoConflict\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#checkValueType\"\u003EcheckValueType\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#deepClone\"\u003EdeepClone\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch2 name=\"集合\"\u003E\n\u003Ca id=\"集合-数组或对象\" class=\"anchor\" href=\"#%E9%9B%86%E5%90%88-%E6%95%B0%E7%BB%84%E6%88%96%E5%AF%B9%E8%B1%A1\"\u003E\u003C/a\u003E集合 (数组或对象)\u003C/h2\u003E\n\u003Ch4 name=\"each\"\u003E\n\u003Ca id=\"each\" class=\"anchor\" href=\"#each\"\u003E\u003C/a\u003Eeach\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.each(list, function, [context])\u003C/code\u003E 遍历集合中的每一个元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String|Set|Map，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.each([1,2],(value,key,list)=\u0026gt;{\n\tconsole.log(value,key,list) // 1 0 [1,2]\n})\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"map\"\u003E\n\u003Ca id=\"map\" class=\"anchor\" href=\"#map\"\u003E\u003C/a\u003Emap\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.map(list, function, [context])\u003C/code\u003E 将集合中的每一个元素转换成function的返回值，返回值是原来的数据类型。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.map([1,2],value=\u0026gt;value+1) // [2,3]\n_.map({a:2,b:3},value=\u0026gt;value+1) // {a:3,b:4}\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"reduce\"\u003E\n\u003Ca id=\"reduce\" class=\"anchor\" href=\"#reduce\"\u003E\u003C/a\u003Ereduce\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.reduce(list, function, [context])\u003C/code\u003E 迭代集合中的元素，将每次迭代的值保存在memo参数中。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(memo,value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.reduce([1,2,3],(memo,value)=\u0026gt;value+memo) // 6 \n_.reduce({a:2,b:3},(memo,value)=\u0026gt;value+memo) // 5\n_.reduce('str',(memo,value)=\u0026gt;value+'-'+memo) // s-t-r\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"find\"\u003E\n\u003Ca id=\"find\" class=\"anchor\" href=\"#find\"\u003E\u003C/a\u003Efind\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.find(list, function, [context])\u003C/code\u003E 在集合查找符合\u003Cstrong\u003Efunction\u003C/strong\u003E 返回值的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.find([1,2,3],value=\u0026gt;value === 3) // 3 \n_.find({a:2,b:3},value=\u0026gt;value === 3) // 3\n_.find([{a:2},{a:3}],obj=\u0026gt;obj.a === 3) // {a:3}\n_.find('str',value=\u0026gt;value == 't') // t\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"filter\"\u003E\n\u003Ca id=\"filter\" class=\"anchor\" href=\"#filter\"\u003E\u003C/a\u003Efilter\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.filter(list, function, [context])\u003C/code\u003E 返回在集合中符合\u003Cstrong\u003Efunction\u003C/strong\u003E 返回值的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.filter([1,2,3],value=\u0026gt;value \u0026gt;= 2) // [2,3] \n_.filter({a:2,b:3},value=\u0026gt;value === 3) // {b:3}\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"every\"\u003E\n\u003Ca id=\"every\" class=\"anchor\" href=\"#every\"\u003E\u003C/a\u003Eevery\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.every(list, function, [context])\u003C/code\u003E 在集合中每一项元素都符合条件，返回true。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.every([1,2,3],value=\u0026gt;value ！= 0) // true\n_.every([1,2,3],value=\u0026gt;value \u0026gt;= 2) // false\n_.every({a:2,b:3},value=\u0026gt;value != 0) // true\n_.every('sss',value=\u0026gt;value == 's') // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"some\"\u003E\n\u003Ca id=\"some\" class=\"anchor\" href=\"#some\"\u003E\u003C/a\u003Esome\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.some(list, function, [context])\u003C/code\u003E 在集合中每一项元素都符合条件，返回true。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.some([1,2,3],value=\u0026gt;value == 0) // false\n_.some([1,2,3],value=\u0026gt;value == 2) // true\n_.some({a:2,b:3},value=\u0026gt;value != 0) // true\n_.some('str',value=\u0026gt;value == 's') // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"max\"\u003E\n\u003Ca id=\"max\" class=\"anchor\" href=\"#max\"\u003E\u003C/a\u003Emax\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.max(list)\u003C/code\u003E 返回集合中最大的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，只支持数字\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.max([1,2,3]) // 3\n_.max({a:1,b:2}) // 2\n_.max({}) // undefined\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"min\"\u003E\n\u003Ca id=\"min\" class=\"anchor\" href=\"#min\"\u003E\u003C/a\u003Emin\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.min(list)\u003C/code\u003E 返回集合中最大的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，只支持数字\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.min([1,2,3]) // 1\n_.min({a:1,b:2}) // 1\n_.min({}) // undefined\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"contains\"\u003E\n\u003Ca id=\"contains\" class=\"anchor\" href=\"#contains\"\u003E\u003C/a\u003Econtains\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.contains(list,ele)\u003C/code\u003E 包含指定元素，返回true。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object | Array | String, \u003Cstrong\u003Eele\u003C/strong\u003E可以是 Object | Array | String | Number | Boolean | null | undefined | NaN。\u003Cstrong\u003E注意\u003C/strong\u003E当是Object | Array 会使用 \u003Ca href=\"#isEqual\"\u003EisEqual\u003C/a\u003E 进行判断\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.contains('st','t') // true\n_.contains({a:1,b:2},2) // true\n_.contains([1,2],2) // true\n_.contains([{a:1}],{a:1}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"size\"\u003E\n\u003Ca id=\"size\" class=\"anchor\" href=\"#size\"\u003E\u003C/a\u003Esize\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.size(list)\u003C/code\u003E 返回元素长度。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object | Array | String\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.size('st') // 2\n_.size({a:1,b:2}) // 2\n_.size([1,2,3]) // 3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isEmpty\"\u003E\n\u003Ca id=\"isempty\" class=\"anchor\" href=\"#isempty\"\u003E\u003C/a\u003EisEmpty\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.isEmpty(list)\u003C/code\u003E 集合是否为空 。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object | Array | String\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isEmpty('st') // false\n_.isEmpty({a:1,b:2}) // false\n_.isEmpty([]) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"数组\"\u003E\n\u003Ca id=\"数组\" class=\"anchor\" href=\"#%E6%95%B0%E7%BB%84\"\u003E\u003C/a\u003E数组\u003C/h2\u003E\n\u003Ch4 name=\"last\"\u003E\n\u003Ca id=\"last\" class=\"anchor\" href=\"#last\"\u003E\u003C/a\u003Elast\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.last(list)\u003C/code\u003E 返回数组最后的元素。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.last([2,3,1]) // 1\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"unique\"\u003E\n\u003Ca id=\"unique\" class=\"anchor\" href=\"#unique\"\u003E\u003C/a\u003Eunique\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.unique(list)\u003C/code\u003E 数组去重\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.unique([2,3,1,1]) // [2,3,1]\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"range\"\u003E\n\u003Ca id=\"range\" class=\"anchor\" href=\"#range\"\u003E\u003C/a\u003Erange\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.range([start],end,[step])\u003C/code\u003E 生成数组\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.range(4) // [0,1,2,3]\n_.range(1,4) // [1,2,3]\n_.range(2,8,2) // [2,4,6]\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"函数\"\u003E\n\u003Ca id=\"函数\" class=\"anchor\" href=\"#%E5%87%BD%E6%95%B0\"\u003E\u003C/a\u003E函数\u003C/h2\u003E\n\u003Ch4 name=\"partial\"\u003E\n\u003Ca id=\"partial\" class=\"anchor\" href=\"#partial\"\u003E\u003C/a\u003Epartial\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.partial(fn,args)\u003C/code\u003E 偏函数。使用null为占位符，保存已有参数，返回一个函数，\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Efunction add(a,b) {return a+b}\nlet add2 = _.partial(add,null,2) \nadd2(3) // 5\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"memoize\"\u003E\n\u003Ca id=\"memoize\" class=\"anchor\" href=\"#memoize\"\u003E\u003C/a\u003Ememoize\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.memoize(fn)\u003C/code\u003E 缓存函数运行后的结果。如果缓存中已有，则直接返回。只支持单个参数的函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet factorial = _.memoize(function (n) {\n        let result = 1;\n        return _factorial(n);\n        function _factorial(n) {\n            count++; // 调用次数\n            result *= n;\n            if (n == 1) {\n                return result;\n            }\n            return _factorial(--n) // es6的尾调用优化\n        }\n});\nlet count = 0; // 调用factorial次数\nfactory(5) // 120,count == 5\ncount = 0;\nfactory(5) // 120, count == 0\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"curry\"\u003E\n\u003Ca id=\"curry\" class=\"anchor\" href=\"#curry\"\u003E\u003C/a\u003Ecurry\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.curry(fn,args)\u003C/code\u003E 柯里化。将函数变成一元函数（单个参数）的过程。用处：根据一个模板函数，生成多个函数。\u003Cstrong\u003E注意\u003C/strong\u003E fn参数中有es6 ...rest 无法进行柯里化\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Efunction add(a,b) {\n    return a+b;\n}\nlet three = _.curry(add)(1,2);\nlet add2 = _.curry(add)(2);\nthree // 3\nadd2(1) // 3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"delay\"\u003E\n\u003Ca id=\"delay\" class=\"anchor\" href=\"#delay\"\u003E\u003C/a\u003Edelay\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.delay(fn,delay,[*args])\u003C/code\u003E 延迟运行。\u003Cstrong\u003Eargs\u003C/strong\u003E为fn的参数，可以多个\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.delay(alert,1000,'hello')\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"throttle\"\u003E\n\u003Ca id=\"throttle\" class=\"anchor\" href=\"#throttle\"\u003E\u003C/a\u003Ethrottle\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.throttle(fn,[delay])\u003C/code\u003E 节流函数。在 delay ms内不停触发只运行一次,默认200ms。返回一个函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet fn = _.throttle(alert,100);\nwindow.onmousemove = function() {fn('hello')} // hello\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"debounce\"\u003E\n\u003Ca id=\"debounce\" class=\"anchor\" href=\"#debounce\"\u003E\u003C/a\u003Edebounce\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.debounce(fn,[wait])\u003C/code\u003E 防抖函数。运行一次后过 wait ms后才能运行。返回一个函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet fn = _.debounce(alert,500);\nwindow.onmousemove = function() {fn('hello')} // hello\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"once\"\u003E\n\u003Ca id=\"once\" class=\"anchor\" href=\"#once\"\u003E\u003C/a\u003Eonce\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.once(fn,[context])\u003C/code\u003E 页面生命周期内只运行一次fn。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet fn = _.once(alert)\nfn('once')\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"pipe\"\u003E\n\u003Ca id=\"pipe\" class=\"anchor\" href=\"#pipe\"\u003E\u003C/a\u003Epipe\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.pipe(*function)\u003C/code\u003E 管道函数。从左往右运行，返回最后函数运行的值\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet mapAbs = array=\u0026gt;{\n    return _.map(array,value=\u0026gt;Math.abs(value))\n}\nlet max = array=\u0026gt;{\n    return Math.max(...array)\n}\n\nlet fn = _.pipe(mapAbs,max)\n// let fn = _.pipe(mapAbs ,_.tap((v)=\u0026gt;{log(v)}),max) · // 可用_.tap 调试运行过程的值\nfn([1,-3,2]) // 3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"对象\"\u003E\n\u003Ca id=\"对象\" class=\"anchor\" href=\"#%E5%AF%B9%E8%B1%A1\"\u003E\u003C/a\u003E对象\u003C/h2\u003E\n\u003Ch4 name=\"hasKey\"\u003E\n\u003Ca id=\"haskey\" class=\"anchor\" href=\"#haskey\"\u003E\u003C/a\u003EhasKey\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.hasKey(obj,key)\u003C/code\u003E obj是否有key 这个属性。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.hasKey({a:1},'a') // true\n_.hasKey({},'a') // false\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isEqual\"\u003E\n\u003Ca id=\"isequal\" class=\"anchor\" href=\"#isequal\"\u003E\u003C/a\u003EisEqual\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.isEqual(obj,other)\u003C/code\u003E 判断obj,other 是否深度相等。类型可以是 \u003Cstrong\u003E引用类型：\u003C/strong\u003E Object | Array | Date | DOM元素, \u003Cstrong\u003E基本数据类型：\u003C/strong\u003E String | NUmber | Boolean | Null | undefined | NaN。遇到第一个false会退出。\u003Cstrong\u003E注意：\u003C/strong\u003E Array 与顺序有关，Object 与顺序无关。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isEqual([],[])  //true\n_.isEqual({},{}）  //true\n_.isEqual({a:1},{a:1})  //true\n_.isEqual({b:1,a:2},{a:2,b:1})  //true，Object 顺序无关\n_.isEqual({a:[1,false]},{a:[1,false]})  //true\n_.isEqual({a:{a:NaN}},{a:{a:NaN}})  //true\n_.isEqual([null,'s'],[null,'s'])  //true\n_.isEqual([[1,2],{a:1}],[[1,2],{a:1}])  //true\n_.isEqual([1,2],[2,1])  //false\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"inMatch\"\u003E\n\u003Ca id=\"inmatch\" class=\"anchor\" href=\"#inmatch\"\u003E\u003C/a\u003EinMatch\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.inMatch(obj,properties)\u003C/code\u003E 对象 是否包含 properties。相等类型可以是 \u003Cstrong\u003E引用类型：\u003C/strong\u003E Object | Array | Date | DOM元素, \u003Cstrong\u003E基本数据类型：\u003C/strong\u003E String | NUmber | Boolean | Null | undefined | NaN。遇到第一个false会退出。\u003Cstrong\u003E注意：\u003C/strong\u003E Array 与顺序有关，Object 与顺序无关；Array 和 Object 会使用\u003Ca href=\"#isEqual\"\u003EisEqual\u003C/a\u003E进行判断。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.inMatch({},{})  //true\n_.inMatch({a:1},{a:1})  //true\n_.inMatch({b:1,a:{name:1,age:2}},{a:{age:2,name:1}})  //true，Object 顺序无关\n_.inMatch({},{a:1}) // false\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isObject\"\u003E\n\u003Ca id=\"isobject\" class=\"anchor\" href=\"#isobject\"\u003E\u003C/a\u003EisObject\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isObject(obj)\u003C/code\u003E obj是否为一个对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isObject({a:1}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isArray\"\u003E\n\u003Ca id=\"isarray\" class=\"anchor\" href=\"#isarray\"\u003E\u003C/a\u003EisArray\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isArray(obj)\u003C/code\u003E obj是否为一个数组\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isArray({a:1}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isFunction\"\u003E\n\u003Ca id=\"isfunction\" class=\"anchor\" href=\"#isfunction\"\u003E\u003C/a\u003EisFunction\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isFunction(obj)\u003C/code\u003E obj是否为一个函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isFunction(()=\u0026gt;{}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isPromise\"\u003E\n\u003Ca id=\"ispromise\" class=\"anchor\" href=\"#ispromise\"\u003E\u003C/a\u003EisPromise\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isPromise(obj)\u003C/code\u003E obj是否为一个Promise 对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet promise = new Promise((resovle,reject)=\u0026gt;{})\n_.isPromise(promise) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isDate\"\u003E\n\u003Ca id=\"isdate\" class=\"anchor\" href=\"#isdate\"\u003E\u003C/a\u003EisDate\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isDate(obj)\u003C/code\u003E obj是否为一个日期对象\u003C/p\u003E\n\u003Cpre lang=\"isDate\" class=\"isDate\"\u003E\u003Ccode\u003E_.isDate(new Date()) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isRegExp\"\u003E\n\u003Ca id=\"isregexp\" class=\"anchor\" href=\"#isregexp\"\u003E\u003C/a\u003EisRegExp\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isRegExp(obj)\u003C/code\u003E obj是否为一个正则对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isRegExp(/1/) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isMap\"\u003E\n\u003Ca id=\"ismap\" class=\"anchor\" href=\"#ismap\"\u003E\u003C/a\u003EisMap\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isMap(obj)\u003C/code\u003E obj是否为一个Map对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isMap(new Map()) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isSet\"\u003E\n\u003Ca id=\"isset\" class=\"anchor\" href=\"#isset\"\u003E\u003C/a\u003EisSet\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isSet(obj)\u003C/code\u003E obj是否为一个Set对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isSet(new Set()) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isString\"\u003E\n\u003Ca id=\"isstring\" class=\"anchor\" href=\"#isstring\"\u003E\u003C/a\u003EisString\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isString(obj)\u003C/code\u003E obj是否为一个字符串\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isString('') // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isNumber\"\u003E\n\u003Ca id=\"isnumber\" class=\"anchor\" href=\"#isnumber\"\u003E\u003C/a\u003EisNumber\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isNumber(obj)\u003C/code\u003E obj是否为一个数字\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isNumber(1) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isNull\"\u003E\n\u003Ca id=\"isnull\" class=\"anchor\" href=\"#isnull\"\u003E\u003C/a\u003EisNull\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isNull(obj)\u003C/code\u003E obj是否为一个null\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isNull(null) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isNaN\"\u003E\n\u003Ca id=\"isnan\" class=\"anchor\" href=\"#isnan\"\u003E\u003C/a\u003EisNaN\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isNaN(obj)\u003C/code\u003E obj是否为一个NaN\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isNaN(NaN) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isUndefined\"\u003E\n\u003Ca id=\"isundefined\" class=\"anchor\" href=\"#isundefined\"\u003E\u003C/a\u003EisUndefined\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isUndefined(obj)\u003C/code\u003E obj是否为一个undefined\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isUndefined(undefined) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isSymbol\"\u003E\n\u003Ca id=\"issymbol\" class=\"anchor\" href=\"#issymbol\"\u003E\u003C/a\u003EisSymbol\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isSymbol(obj)\u003C/code\u003E obj是否为一个Symbol\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet symbol = new Symbol('s')\n_.isSymbol(symbol) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"实用功能\"\u003E\n\u003Ca id=\"实用功能\" class=\"anchor\" href=\"#%E5%AE%9E%E7%94%A8%E5%8A%9F%E8%83%BD\"\u003E\u003C/a\u003E实用功能\u003C/h2\u003E\n\u003Ch4 name=\"noConflict\"\u003E\n\u003Ca id=\"noconflict\" class=\"anchor\" href=\"#noconflict\"\u003E\u003C/a\u003EnoConflict\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.noConflict()\u003C/code\u003E 放弃_的引用（在浏览端有效）,返回 _ ；\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet my = _.noConflict(); // _ is undefined\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"formatDate\"\u003E\n\u003Ca id=\"formatdate\" class=\"anchor\" href=\"#formatdate\"\u003E\u003C/a\u003EformatDate\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.formatDate(date,format)\u003C/code\u003E 格式化日期。如果不传参数，默认当前日期。 ；\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet date = new Date('2020/5/1 18:35:5');\n// 正常用法 _.formatDate(date,'yyyy-MM-dd')\n// 固定参数重复使用，可用柯里化或偏函数`_.partial(_.formatDate,date,null)`\nlet formatDate = _.curry(_.formatDate)(date) \nformatDate('yyyy-MM-dd') // 2020-05-01\nformatDate('M月d日') // 5月1日\n/*\n  yyyy 年\n  M 月 \n  MM 月 补0\n  d 日\n  dd 补0\n  H 小时\n  HH 小时 补0\n  m 分钟\n  mm 分钟 补0\n  s 秒 \n  ss 秒 补0\n*/\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"random\"\u003E\n\u003Ca id=\"random\" class=\"anchor\" href=\"#random\"\u003E\u003C/a\u003Erandom\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.random(min,[max])\u003C/code\u003E 返回min - max 的随机数。只有一个参数，返回0- min ；不包括max .\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.random(2); // 0 1\n_.random(2,4) // 2,3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"checkValueType\"\u003E\n\u003Ca id=\"checkvaluetype\" class=\"anchor\" href=\"#checkvaluetype\"\u003E\u003C/a\u003EcheckValueType\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.checkValueType(variable)\u003C/code\u003E 检测变量类型。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003EcheckValueType([]) // 'array'\ncheckValueType({}) // 'object'\ncheckValueType(Promise) // 'promise'\ncheckValueType(()=\u0026gt;{}) // 'function'\ncheckValueType(/1/) // 'regexp'\ncheckValueType(\"\") // 'string'\ncheckValueType(123) // 'number'\ncheckValueType(true) // 'boolean'\ncheckValueType(undefined) // 'undefined'\ncheckValueType(null) // 'null'\ncheckValueType(undefined) // 'symbol'\ncheckValueType(NaN) // 'NaN'\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"deepClone\"\u003E\n\u003Ca id=\"deepclone\" class=\"anchor\" href=\"#deepclone\"\u003E\u003C/a\u003EdeepClone\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.deepClone(obj)\u003C/code\u003E 深拷贝。支持引用类型（Object Array Date）、基本数据类型（String Number Boolean undefined null NaN ）\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.deepClone({a:1,b:2}) // {a:1,b:2}\n_.deepClone([1,2]) // [1,2]\n\u003C/code\u003E\u003C/pre\u003E"}],"content":{"2161093":"\u003Ch1\u003E\n\u003Ca id=\"javascript-函数式编程的接口库\" class=\"anchor\" href=\"#javascript-%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%BA%93\"\u003E\u003C/a\u003Ejavascript 函数式编程的接口库\u003C/h1\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003E模仿\u003Ca href=\"http://www.underscore-js.com/sourceread/index.html\"\u003Eunderscore.js\u003C/a\u003E实现自己的函数库，增加额外自己常用的函数，用于学习函数式编程\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Cul\u003E\n\u003Cli\u003E使用es6实现部分\u003Ca href=\"http://www.underscore-js.com/\"\u003Eunderscore.js\u003C/a\u003E的函数，增加自己常用的\u003C/li\u003E\n\u003Cli\u003E增加自己常用到的函数，如\u003Ccode\u003EonceDelay\u003C/code\u003E(运行一次后在指定时间后才能再次运行)\u003C/li\u003E\n\u003Cli\u003E错误处理：\n\u003Cul\u003E\n\u003Cli\u003E指定参数类型才能运行函数\u003C/li\u003E\n\u003Cli\u003E检测运行时函数是否为必须，必须时没传函数控制台输出提示信息\u003C/li\u003E\n\u003C/ul\u003E\n\u003C/li\u003E\n\u003Cli\u003E单元测试\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch2\u003E\n\u003Ca id=\"目录结构\" class=\"anchor\" href=\"#%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84\"\u003E\u003C/a\u003E目录结构\u003C/h2\u003E\n\u003Cpre\u003E\u003Ccode\u003E+ browserTest // 浏览器单元测试环境  \n  |-- index.html\n+ lib  \n  |-- functional.js // 函数库  \n+ mochawesome-report  \n  |-- mochawesome.html // 单元测试报告\n+ doc 文档  \n  |-- index_with_tree\n+ test 单元测试  \n  |-- functional.test.js // 测试用例代码  \n  |-- spec.html // 测试用例规格  \n\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2\u003E\n\u003Ca id=\"运行单元测试\" class=\"anchor\" href=\"#%E8%BF%90%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95\"\u003E\u003C/a\u003E运行单元测试\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003Enode\u003C/strong\u003E\u003C/p\u003E\n\u003Cpre\u003E\u003Ccode\u003Enpm install -g mocha mochawesome\nnpm install\nnpm run test\n\n// 生成测试报告\nnpm run report\n// 生成测试用例规格\nnpm run spec\n\u003C/code\u003E\u003C/pre\u003E\n\u003Cp\u003E\u003Cstrong\u003E浏览器\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E直接打开\u003Ccode\u003EbrowserTest/index.html\u003C/code\u003E\u003C/p\u003E","2161094":"\u003Cp\u003E\u003Cstrong\u003E安装\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E浏览器： 通过\u003Ccode\u003E\u0026lt;script\u0026gt;\u003C/code\u003E引入，默认绑定全局变量 _\u003C/li\u003E\n\u003Cli\u003Enode: \u003Ccode\u003Erequire\u003C/code\u003E 引入\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E统一\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E传入 \u003Cstrong\u003E[context]\u003C/strong\u003E，在function中的this会指向[context]\u003C/li\u003E\n\u003Cli\u003E当传入不合符函数的参数类型时，会返回自身（有想过返回undefined），不会去运行函数\u003C/li\u003E\n\u003Cli\u003E当函数参数中 \u003Cstrong\u003Efunction\u003C/strong\u003E 为必传时，没传控制台会输出提示信息\u003C/li\u003E\n\u003Cli\u003E参数带 [ ] 为选填，如[context]\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E9%9B%86%E5%90%88\"\u003E集合(数组或对象)\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#each\"\u003Eeach\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#map\"\u003Emap\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#reduce\"\u003Ereduce\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#find\"\u003Efind\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#filter\"\u003Efilter\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#every\"\u003Eevery\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#some\"\u003Esome\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#max\"\u003Emax\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#min\"\u003Emin\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#contains\"\u003Econtains\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#size\"\u003Esize\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isEmpty\"\u003EisEmpty\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E6%95%B0%E7%BB%84\"\u003E数组\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#last\"\u003Elast\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#unique\"\u003Eunique\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#range\"\u003Erange\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E5%87%BD%E6%95%B0\"\u003E函数\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#partial\"\u003Epartial\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#memoize\"\u003Ememoize\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#curry\"\u003Ecurry\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#delay\"\u003Edelay\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#curry\"\u003Ethrottle\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#debounce\"\u003Edebounce\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#once\"\u003Eonce\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#pipe\"\u003Epipe\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E5%AF%B9%E8%B1%A1\"\u003E对象\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#hasKey\"\u003EhasKey\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isEqual\"\u003EisEqual\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#inMatch\"\u003EinMatch\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isObject\"\u003EisObject\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isArray\"\u003EisArray\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isFunction\"\u003EisFunction\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isPromise\"\u003EisPromise\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isDate\"\u003EisDate\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isRegExp\"\u003EisRegExp\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isMap\"\u003EisMap\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isSet\"\u003EisSet\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isString\"\u003EisString\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isNumber\"\u003EisNumber\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isNull\"\u003EisNull\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isNaN\"\u003EisNaN\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isUndefined\"\u003EisUndefined\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#isSymbol\"\u003EisSymbol\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Ca href=\"#%E5%AE%9E%E7%94%A8%E5%8A%9F%E8%83%BD\"\u003E实用功能\u003C/a\u003E\u003C/strong\u003E\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"#random\"\u003Erandom\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#formatDate\"\u003EformatDate\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#noConflict\"\u003EnoConflict\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#checkValueType\"\u003EcheckValueType\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"#deepClone\"\u003EdeepClone\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch2 name=\"集合\"\u003E\n\u003Ca id=\"集合-数组或对象\" class=\"anchor\" href=\"#%E9%9B%86%E5%90%88-%E6%95%B0%E7%BB%84%E6%88%96%E5%AF%B9%E8%B1%A1\"\u003E\u003C/a\u003E集合 (数组或对象)\u003C/h2\u003E\n\u003Ch4 name=\"each\"\u003E\n\u003Ca id=\"each\" class=\"anchor\" href=\"#each\"\u003E\u003C/a\u003Eeach\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.each(list, function, [context])\u003C/code\u003E 遍历集合中的每一个元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String|Set|Map，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.each([1,2],(value,key,list)=\u0026gt;{\n\tconsole.log(value,key,list) // 1 0 [1,2]\n})\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"map\"\u003E\n\u003Ca id=\"map\" class=\"anchor\" href=\"#map\"\u003E\u003C/a\u003Emap\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.map(list, function, [context])\u003C/code\u003E 将集合中的每一个元素转换成function的返回值，返回值是原来的数据类型。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.map([1,2],value=\u0026gt;value+1) // [2,3]\n_.map({a:2,b:3},value=\u0026gt;value+1) // {a:3,b:4}\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"reduce\"\u003E\n\u003Ca id=\"reduce\" class=\"anchor\" href=\"#reduce\"\u003E\u003C/a\u003Ereduce\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.reduce(list, function, [context])\u003C/code\u003E 迭代集合中的元素，将每次迭代的值保存在memo参数中。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(memo,value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.reduce([1,2,3],(memo,value)=\u0026gt;value+memo) // 6 \n_.reduce({a:2,b:3},(memo,value)=\u0026gt;value+memo) // 5\n_.reduce('str',(memo,value)=\u0026gt;value+'-'+memo) // s-t-r\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"find\"\u003E\n\u003Ca id=\"find\" class=\"anchor\" href=\"#find\"\u003E\u003C/a\u003Efind\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.find(list, function, [context])\u003C/code\u003E 在集合查找符合\u003Cstrong\u003Efunction\u003C/strong\u003E 返回值的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.find([1,2,3],value=\u0026gt;value === 3) // 3 \n_.find({a:2,b:3},value=\u0026gt;value === 3) // 3\n_.find([{a:2},{a:3}],obj=\u0026gt;obj.a === 3) // {a:3}\n_.find('str',value=\u0026gt;value == 't') // t\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"filter\"\u003E\n\u003Ca id=\"filter\" class=\"anchor\" href=\"#filter\"\u003E\u003C/a\u003Efilter\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.filter(list, function, [context])\u003C/code\u003E 返回在集合中符合\u003Cstrong\u003Efunction\u003C/strong\u003E 返回值的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.filter([1,2,3],value=\u0026gt;value \u0026gt;= 2) // [2,3] \n_.filter({a:2,b:3},value=\u0026gt;value === 3) // {b:3}\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"every\"\u003E\n\u003Ca id=\"every\" class=\"anchor\" href=\"#every\"\u003E\u003C/a\u003Eevery\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.every(list, function, [context])\u003C/code\u003E 在集合中每一项元素都符合条件，返回true。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.every([1,2,3],value=\u0026gt;value ！= 0) // true\n_.every([1,2,3],value=\u0026gt;value \u0026gt;= 2) // false\n_.every({a:2,b:3},value=\u0026gt;value != 0) // true\n_.every('sss',value=\u0026gt;value == 's') // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"some\"\u003E\n\u003Ca id=\"some\" class=\"anchor\" href=\"#some\"\u003E\u003C/a\u003Esome\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.some(list, function, [context])\u003C/code\u003E 在集合中每一项元素都符合条件，返回true。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array|String，\u003Cstrong\u003Efunction\u003C/strong\u003E 的参数是(value, key, list)\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.some([1,2,3],value=\u0026gt;value == 0) // false\n_.some([1,2,3],value=\u0026gt;value == 2) // true\n_.some({a:2,b:3},value=\u0026gt;value != 0) // true\n_.some('str',value=\u0026gt;value == 's') // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"max\"\u003E\n\u003Ca id=\"max\" class=\"anchor\" href=\"#max\"\u003E\u003C/a\u003Emax\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.max(list)\u003C/code\u003E 返回集合中最大的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，只支持数字\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.max([1,2,3]) // 3\n_.max({a:1,b:2}) // 2\n_.max({}) // undefined\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"min\"\u003E\n\u003Ca id=\"min\" class=\"anchor\" href=\"#min\"\u003E\u003C/a\u003Emin\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.min(list)\u003C/code\u003E 返回集合中最大的元素。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object|Array，只支持数字\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.min([1,2,3]) // 1\n_.min({a:1,b:2}) // 1\n_.min({}) // undefined\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"contains\"\u003E\n\u003Ca id=\"contains\" class=\"anchor\" href=\"#contains\"\u003E\u003C/a\u003Econtains\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.contains(list,ele)\u003C/code\u003E 包含指定元素，返回true。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object | Array | String, \u003Cstrong\u003Eele\u003C/strong\u003E可以是 Object | Array | String | Number | Boolean | null | undefined | NaN。\u003Cstrong\u003E注意\u003C/strong\u003E当是Object | Array 会使用 \u003Ca href=\"#isEqual\"\u003EisEqual\u003C/a\u003E 进行判断\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.contains('st','t') // true\n_.contains({a:1,b:2},2) // true\n_.contains([1,2],2) // true\n_.contains([{a:1}],{a:1}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"size\"\u003E\n\u003Ca id=\"size\" class=\"anchor\" href=\"#size\"\u003E\u003C/a\u003Esize\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.size(list)\u003C/code\u003E 返回元素长度。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object | Array | String\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.size('st') // 2\n_.size({a:1,b:2}) // 2\n_.size([1,2,3]) // 3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isEmpty\"\u003E\n\u003Ca id=\"isempty\" class=\"anchor\" href=\"#isempty\"\u003E\u003C/a\u003EisEmpty\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.isEmpty(list)\u003C/code\u003E 集合是否为空 。 \u003Cstrong\u003Elist\u003C/strong\u003E可以是 Object | Array | String\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isEmpty('st') // false\n_.isEmpty({a:1,b:2}) // false\n_.isEmpty([]) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"数组\"\u003E\n\u003Ca id=\"数组\" class=\"anchor\" href=\"#%E6%95%B0%E7%BB%84\"\u003E\u003C/a\u003E数组\u003C/h2\u003E\n\u003Ch4 name=\"last\"\u003E\n\u003Ca id=\"last\" class=\"anchor\" href=\"#last\"\u003E\u003C/a\u003Elast\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.last(list)\u003C/code\u003E 返回数组最后的元素。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.last([2,3,1]) // 1\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"unique\"\u003E\n\u003Ca id=\"unique\" class=\"anchor\" href=\"#unique\"\u003E\u003C/a\u003Eunique\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.unique(list)\u003C/code\u003E 数组去重\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.unique([2,3,1,1]) // [2,3,1]\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"range\"\u003E\n\u003Ca id=\"range\" class=\"anchor\" href=\"#range\"\u003E\u003C/a\u003Erange\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.range([start],end,[step])\u003C/code\u003E 生成数组\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.range(4) // [0,1,2,3]\n_.range(1,4) // [1,2,3]\n_.range(2,8,2) // [2,4,6]\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"函数\"\u003E\n\u003Ca id=\"函数\" class=\"anchor\" href=\"#%E5%87%BD%E6%95%B0\"\u003E\u003C/a\u003E函数\u003C/h2\u003E\n\u003Ch4 name=\"partial\"\u003E\n\u003Ca id=\"partial\" class=\"anchor\" href=\"#partial\"\u003E\u003C/a\u003Epartial\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.partial(fn,args)\u003C/code\u003E 偏函数。使用null为占位符，保存已有参数，返回一个函数，\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Efunction add(a,b) {return a+b}\nlet add2 = _.partial(add,null,2) \nadd2(3) // 5\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"memoize\"\u003E\n\u003Ca id=\"memoize\" class=\"anchor\" href=\"#memoize\"\u003E\u003C/a\u003Ememoize\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.memoize(fn)\u003C/code\u003E 缓存函数运行后的结果。如果缓存中已有，则直接返回。只支持单个参数的函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet factorial = _.memoize(function (n) {\n        let result = 1;\n        return _factorial(n);\n        function _factorial(n) {\n            count++; // 调用次数\n            result *= n;\n            if (n == 1) {\n                return result;\n            }\n            return _factorial(--n) // es6的尾调用优化\n        }\n});\nlet count = 0; // 调用factorial次数\nfactory(5) // 120,count == 5\ncount = 0;\nfactory(5) // 120, count == 0\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"curry\"\u003E\n\u003Ca id=\"curry\" class=\"anchor\" href=\"#curry\"\u003E\u003C/a\u003Ecurry\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.curry(fn,args)\u003C/code\u003E 柯里化。将函数变成一元函数（单个参数）的过程。用处：根据一个模板函数，生成多个函数。\u003Cstrong\u003E注意\u003C/strong\u003E fn参数中有es6 ...rest 无法进行柯里化\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Efunction add(a,b) {\n    return a+b;\n}\nlet three = _.curry(add)(1,2);\nlet add2 = _.curry(add)(2);\nthree // 3\nadd2(1) // 3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"delay\"\u003E\n\u003Ca id=\"delay\" class=\"anchor\" href=\"#delay\"\u003E\u003C/a\u003Edelay\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.delay(fn,delay,[*args])\u003C/code\u003E 延迟运行。\u003Cstrong\u003Eargs\u003C/strong\u003E为fn的参数，可以多个\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.delay(alert,1000,'hello')\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"throttle\"\u003E\n\u003Ca id=\"throttle\" class=\"anchor\" href=\"#throttle\"\u003E\u003C/a\u003Ethrottle\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.throttle(fn,[delay])\u003C/code\u003E 节流函数。在 delay ms内不停触发只运行一次,默认200ms。返回一个函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet fn = _.throttle(alert,100);\nwindow.onmousemove = function() {fn('hello')} // hello\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"debounce\"\u003E\n\u003Ca id=\"debounce\" class=\"anchor\" href=\"#debounce\"\u003E\u003C/a\u003Edebounce\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.debounce(fn,[wait])\u003C/code\u003E 防抖函数。运行一次后过 wait ms后才能运行。返回一个函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet fn = _.debounce(alert,500);\nwindow.onmousemove = function() {fn('hello')} // hello\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"once\"\u003E\n\u003Ca id=\"once\" class=\"anchor\" href=\"#once\"\u003E\u003C/a\u003Eonce\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.once(fn,[context])\u003C/code\u003E 页面生命周期内只运行一次fn。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet fn = _.once(alert)\nfn('once')\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"pipe\"\u003E\n\u003Ca id=\"pipe\" class=\"anchor\" href=\"#pipe\"\u003E\u003C/a\u003Epipe\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.pipe(*function)\u003C/code\u003E 管道函数。从左往右运行，返回最后函数运行的值\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet mapAbs = array=\u0026gt;{\n    return _.map(array,value=\u0026gt;Math.abs(value))\n}\nlet max = array=\u0026gt;{\n    return Math.max(...array)\n}\n\nlet fn = _.pipe(mapAbs,max)\n// let fn = _.pipe(mapAbs ,_.tap((v)=\u0026gt;{log(v)}),max) · // 可用_.tap 调试运行过程的值\nfn([1,-3,2]) // 3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"对象\"\u003E\n\u003Ca id=\"对象\" class=\"anchor\" href=\"#%E5%AF%B9%E8%B1%A1\"\u003E\u003C/a\u003E对象\u003C/h2\u003E\n\u003Ch4 name=\"hasKey\"\u003E\n\u003Ca id=\"haskey\" class=\"anchor\" href=\"#haskey\"\u003E\u003C/a\u003EhasKey\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.hasKey(obj,key)\u003C/code\u003E obj是否有key 这个属性。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.hasKey({a:1},'a') // true\n_.hasKey({},'a') // false\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isEqual\"\u003E\n\u003Ca id=\"isequal\" class=\"anchor\" href=\"#isequal\"\u003E\u003C/a\u003EisEqual\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.isEqual(obj,other)\u003C/code\u003E 判断obj,other 是否深度相等。类型可以是 \u003Cstrong\u003E引用类型：\u003C/strong\u003E Object | Array | Date | DOM元素, \u003Cstrong\u003E基本数据类型：\u003C/strong\u003E String | NUmber | Boolean | Null | undefined | NaN。遇到第一个false会退出。\u003Cstrong\u003E注意：\u003C/strong\u003E Array 与顺序有关，Object 与顺序无关。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isEqual([],[])  //true\n_.isEqual({},{}）  //true\n_.isEqual({a:1},{a:1})  //true\n_.isEqual({b:1,a:2},{a:2,b:1})  //true，Object 顺序无关\n_.isEqual({a:[1,false]},{a:[1,false]})  //true\n_.isEqual({a:{a:NaN}},{a:{a:NaN}})  //true\n_.isEqual([null,'s'],[null,'s'])  //true\n_.isEqual([[1,2],{a:1}],[[1,2],{a:1}])  //true\n_.isEqual([1,2],[2,1])  //false\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"inMatch\"\u003E\n\u003Ca id=\"inmatch\" class=\"anchor\" href=\"#inmatch\"\u003E\u003C/a\u003EinMatch\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.inMatch(obj,properties)\u003C/code\u003E 对象 是否包含 properties。相等类型可以是 \u003Cstrong\u003E引用类型：\u003C/strong\u003E Object | Array | Date | DOM元素, \u003Cstrong\u003E基本数据类型：\u003C/strong\u003E String | NUmber | Boolean | Null | undefined | NaN。遇到第一个false会退出。\u003Cstrong\u003E注意：\u003C/strong\u003E Array 与顺序有关，Object 与顺序无关；Array 和 Object 会使用\u003Ca href=\"#isEqual\"\u003EisEqual\u003C/a\u003E进行判断。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.inMatch({},{})  //true\n_.inMatch({a:1},{a:1})  //true\n_.inMatch({b:1,a:{name:1,age:2}},{a:{age:2,name:1}})  //true，Object 顺序无关\n_.inMatch({},{a:1}) // false\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isObject\"\u003E\n\u003Ca id=\"isobject\" class=\"anchor\" href=\"#isobject\"\u003E\u003C/a\u003EisObject\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isObject(obj)\u003C/code\u003E obj是否为一个对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isObject({a:1}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isArray\"\u003E\n\u003Ca id=\"isarray\" class=\"anchor\" href=\"#isarray\"\u003E\u003C/a\u003EisArray\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isArray(obj)\u003C/code\u003E obj是否为一个数组\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isArray({a:1}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isFunction\"\u003E\n\u003Ca id=\"isfunction\" class=\"anchor\" href=\"#isfunction\"\u003E\u003C/a\u003EisFunction\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isFunction(obj)\u003C/code\u003E obj是否为一个函数\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isFunction(()=\u0026gt;{}) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isPromise\"\u003E\n\u003Ca id=\"ispromise\" class=\"anchor\" href=\"#ispromise\"\u003E\u003C/a\u003EisPromise\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isPromise(obj)\u003C/code\u003E obj是否为一个Promise 对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet promise = new Promise((resovle,reject)=\u0026gt;{})\n_.isPromise(promise) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isDate\"\u003E\n\u003Ca id=\"isdate\" class=\"anchor\" href=\"#isdate\"\u003E\u003C/a\u003EisDate\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isDate(obj)\u003C/code\u003E obj是否为一个日期对象\u003C/p\u003E\n\u003Cpre lang=\"isDate\" class=\"isDate\"\u003E\u003Ccode\u003E_.isDate(new Date()) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isRegExp\"\u003E\n\u003Ca id=\"isregexp\" class=\"anchor\" href=\"#isregexp\"\u003E\u003C/a\u003EisRegExp\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isRegExp(obj)\u003C/code\u003E obj是否为一个正则对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isRegExp(/1/) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isMap\"\u003E\n\u003Ca id=\"ismap\" class=\"anchor\" href=\"#ismap\"\u003E\u003C/a\u003EisMap\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isMap(obj)\u003C/code\u003E obj是否为一个Map对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isMap(new Map()) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isSet\"\u003E\n\u003Ca id=\"isset\" class=\"anchor\" href=\"#isset\"\u003E\u003C/a\u003EisSet\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isSet(obj)\u003C/code\u003E obj是否为一个Set对象\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isSet(new Set()) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isString\"\u003E\n\u003Ca id=\"isstring\" class=\"anchor\" href=\"#isstring\"\u003E\u003C/a\u003EisString\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isString(obj)\u003C/code\u003E obj是否为一个字符串\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isString('') // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isNumber\"\u003E\n\u003Ca id=\"isnumber\" class=\"anchor\" href=\"#isnumber\"\u003E\u003C/a\u003EisNumber\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isNumber(obj)\u003C/code\u003E obj是否为一个数字\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isNumber(1) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isNull\"\u003E\n\u003Ca id=\"isnull\" class=\"anchor\" href=\"#isnull\"\u003E\u003C/a\u003EisNull\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isNull(obj)\u003C/code\u003E obj是否为一个null\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isNull(null) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isNaN\"\u003E\n\u003Ca id=\"isnan\" class=\"anchor\" href=\"#isnan\"\u003E\u003C/a\u003EisNaN\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isNaN(obj)\u003C/code\u003E obj是否为一个NaN\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isNaN(NaN) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isUndefined\"\u003E\n\u003Ca id=\"isundefined\" class=\"anchor\" href=\"#isundefined\"\u003E\u003C/a\u003EisUndefined\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isUndefined(obj)\u003C/code\u003E obj是否为一个undefined\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.isUndefined(undefined) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"isSymbol\"\u003E\n\u003Ca id=\"issymbol\" class=\"anchor\" href=\"#issymbol\"\u003E\u003C/a\u003EisSymbol\u003C/h4\u003E\n\u003Cp\u003E\u003Ccode\u003E_.isSymbol(obj)\u003C/code\u003E obj是否为一个Symbol\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet symbol = new Symbol('s')\n_.isSymbol(symbol) // true\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch2 name=\"实用功能\"\u003E\n\u003Ca id=\"实用功能\" class=\"anchor\" href=\"#%E5%AE%9E%E7%94%A8%E5%8A%9F%E8%83%BD\"\u003E\u003C/a\u003E实用功能\u003C/h2\u003E\n\u003Ch4 name=\"noConflict\"\u003E\n\u003Ca id=\"noconflict\" class=\"anchor\" href=\"#noconflict\"\u003E\u003C/a\u003EnoConflict\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.noConflict()\u003C/code\u003E 放弃_的引用（在浏览端有效）,返回 _ ；\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet my = _.noConflict(); // _ is undefined\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"formatDate\"\u003E\n\u003Ca id=\"formatdate\" class=\"anchor\" href=\"#formatdate\"\u003E\u003C/a\u003EformatDate\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.formatDate(date,format)\u003C/code\u003E 格式化日期。如果不传参数，默认当前日期。 ；\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003Elet date = new Date('2020/5/1 18:35:5');\n// 正常用法 _.formatDate(date,'yyyy-MM-dd')\n// 固定参数重复使用，可用柯里化或偏函数`_.partial(_.formatDate,date,null)`\nlet formatDate = _.curry(_.formatDate)(date) \nformatDate('yyyy-MM-dd') // 2020-05-01\nformatDate('M月d日') // 5月1日\n/*\n  yyyy 年\n  M 月 \n  MM 月 补0\n  d 日\n  dd 补0\n  H 小时\n  HH 小时 补0\n  m 分钟\n  mm 分钟 补0\n  s 秒 \n  ss 秒 补0\n*/\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"random\"\u003E\n\u003Ca id=\"random\" class=\"anchor\" href=\"#random\"\u003E\u003C/a\u003Erandom\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.random(min,[max])\u003C/code\u003E 返回min - max 的随机数。只有一个参数，返回0- min ；不包括max .\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.random(2); // 0 1\n_.random(2,4) // 2,3\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"checkValueType\"\u003E\n\u003Ca id=\"checkvaluetype\" class=\"anchor\" href=\"#checkvaluetype\"\u003E\u003C/a\u003EcheckValueType\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.checkValueType(variable)\u003C/code\u003E 检测变量类型。\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003EcheckValueType([]) // 'array'\ncheckValueType({}) // 'object'\ncheckValueType(Promise) // 'promise'\ncheckValueType(()=\u0026gt;{}) // 'function'\ncheckValueType(/1/) // 'regexp'\ncheckValueType(\"\") // 'string'\ncheckValueType(123) // 'number'\ncheckValueType(true) // 'boolean'\ncheckValueType(undefined) // 'undefined'\ncheckValueType(null) // 'null'\ncheckValueType(undefined) // 'symbol'\ncheckValueType(NaN) // 'NaN'\n\u003C/code\u003E\u003C/pre\u003E\n\u003Ch4 name=\"deepClone\"\u003E\n\u003Ca id=\"deepclone\" class=\"anchor\" href=\"#deepclone\"\u003E\u003C/a\u003EdeepClone\u003C/h4\u003E \n\u003Cp\u003E\u003Ccode\u003E_.deepClone(obj)\u003C/code\u003E 深拷贝。支持引用类型（Object Array Date）、基本数据类型（String Number Boolean undefined null NaN ）\u003C/p\u003E\n\u003Cpre lang=\"javascript\" class=\"javascript\"\u003E\u003Ccode\u003E_.deepClone({a:1,b:2}) // {a:1,b:2}\n_.deepClone([1,2]) // [1,2]\n\u003C/code\u003E\u003C/pre\u003E"}}</script>